package com.joizhang.seckill.service;

import com.alibaba.fastjson.JSONObject;
import com.joizhang.seckill.api.redis.OrderKey;
import com.joizhang.seckill.api.service.OrderService;
import com.joizhang.seckill.api.vo.*;
import com.joizhang.seckill.mapper.OrderMapper;
import com.joizhang.seckill.model.Order;
import com.joizhang.seckill.model.OrderInfo;
import com.joizhang.seckill.redis.RedisService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Objects;

@DubboService
@Service
public class OrderServiceImpl implements OrderService {

    final OrderMapper orderMapper;

    final RedisService redisService;

    @Autowired
    public OrderServiceImpl(OrderMapper orderMapper, RedisService redisService) {
        this.orderMapper = orderMapper;
        this.redisService = redisService;
    }

    @Override
    public Integer countOrderByUserIdGoodsId(Long userId, Long goodsId) {
        Objects.requireNonNull(userId);
        Objects.requireNonNull(goodsId);
        return orderMapper.countOrderByUserIdGoodsId(userId, goodsId);
    }

    @Override
    public OrderVo getOrderFromCache(UserVo userVo, Long goodsId) {
        OrderVo orderVo;
        String key = userVo.getId() + "_" + goodsId;
        JSONObject jsonObject = redisService.getHashAll(OrderKey.SECKILL_ORDER, key);
        if (jsonObject.isEmpty()) {
            Order order = orderMapper.getOrderByUserIdGoodsId(userVo.getId(), goodsId);
            if (Objects.isNull(order)) {
                return null;
            }
            OrderInfo orderInfo = orderMapper.getOrderInfoById(order.getOrderInfoId());
            orderVo = new OrderVo();
            BeanUtils.copyProperties(orderInfo, orderVo);
            orderVo.setOrderInfoId(order.getOrderInfoId());
            orderVo.setUserId(userVo.getId());
            jsonObject = JSONObject.parseObject(JSONObject.toJSONString(orderVo));
            redisService.setHashAll(OrderKey.SECKILL_ORDER, key, jsonObject);
        }
        orderVo = JSONObject.toJavaObject(jsonObject, OrderVo.class);
        return orderVo;
    }

    @Override
    public OrderInfoVo getOrderInfoById(Long orderId) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        OrderInfo orderInfo = orderMapper.getOrderInfoById(orderId);
        if (!Objects.isNull(orderInfo)) {
            BeanUtils.copyProperties(orderInfo, orderInfoVo);
        }
        return orderInfoVo;
    }

    /**
     * 因为要同时分别在订单详情表和秒杀订单表都新增一条数据，所以要保证两个操作是一个事物
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createOrder(UserVo userVo, GoodsVo goodsVo, SecKillGoodsVo secKillGoodsVo) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userVo.getId());
        orderInfo.setGoodsId(goodsVo.getId());
        orderInfo.setDeliveryAddrId(0L);
        orderInfo.setGoodsName(goodsVo.getGoodsName());
        orderInfo.setGoodsPrice(goodsVo.getGoodsPrice());
        orderInfo.setGoodsCount(1);
        orderInfo.setGoodsPay(secKillGoodsVo.getSecKillPrice());
        orderInfo.setOrderChannel(1);
        orderInfo.setStatus(0);
        orderInfo.setCreateDate(LocalDateTime.now());
        orderMapper.insertOrderInfo(orderInfo);

        Order order = new Order();
        order.setOrderInfoId(orderInfo.getId());
        order.setUserId(userVo.getId());
        order.setGoodsId(goodsVo.getId());
        orderMapper.insertOrder(order);

        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(orderInfo, orderVo);
        orderVo.setOrderInfoId(orderInfo.getId());
        orderVo.setUserId(userVo.getId());
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(orderVo));
        String key = userVo.getId() + "_" + goodsVo.getId();
        redisService.setHashAll(OrderKey.SECKILL_ORDER, key, jsonObject);
    }

}
